package com.rongcheng.frc.androidlib.ui.player;

import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.MediaController;

import java.io.IOException;

/**
 * Created by frc on 16-6-14.
 */
public class LstVideoView extends SurfaceView implements MediaController.MediaPlayerControl {

    public static final String TAG = LstVideoView.class.getSimpleName();
    private int mVideoWidth;
    private int mVideoHeight;
    private int mSurfaceWidth;
    private int mSurfaceHeight;
    private SurfaceHolder mSurfaceHolder = null;
    private int mDuration;
    private Uri mUri;
    private Context mContext;
    private int mCurrentState = MediaPlayerStatus.STATE_IDLE;
    private int mTargetState = MediaPlayerStatus.STATE_IDLE;

    private MediaPlayer mMediaPlayer = null;
    private int mSeekWhenPrepared;
    private MediaController mMediaController;
    protected int lastSeekWhenPrepared = 0;

    private boolean fullScreen;

    public LstVideoView(Context context) {
        super(context, null);
    }

    public LstVideoView(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
    }

    public LstVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        initVideoView();
    }

    private void initVideoView() {
        mVideoHeight = 0;
        mVideoWidth = 0;
        getHolder().addCallback(mSHCallback);
        setFocusable(true);
        setFocusableInTouchMode(true);
        requestFocus();
        mCurrentState = MediaPlayerStatus.STATE_IDLE;
        mTargetState = MediaPlayerStatus.STATE_IDLE;
        StateChange(mCurrentState);


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
        int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
        if (!fullScreen) {
            if (mVideoWidth > 0 && mVideoHeight > 0) {
                if (mVideoWidth * height > width * mVideoHeight) {//按照视屏的高宽比 调整播放器的高宽比
                    height = width * mVideoHeight / mVideoWidth;
                } else if (mVideoWidth * height < width * mVideoHeight) {
                    width = height * mVideoHeight / mVideoHeight;
                } else {

                }
            }
        }
        setMeasuredDimension(width, height);

    }

    SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
            mSurfaceHolder = surfaceHolder;
            openVideo();

        }

        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int w, int h) {
            mSurfaceWidth = w;
            mSurfaceHeight = h;
            boolean isValidState = (mTargetState == MediaPlayerStatus.STATE_PLAYING);
            boolean hasValidSize = (mVideoWidth == w && mVideoHeight == h);
            if (mMediaPlayer != null && isValidState && hasValidSize) {
                if (mSeekWhenPrepared != 0) {
                    seekTo(mSeekWhenPrepared);
                }
                start();
                if (mMediaController != null) {
                    mMediaController.show();
                }
                release(true);
            }

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
            mSurfaceHolder = null;
            if (mMediaController != null) {
                mMediaController.hide();
            }
            lastSeekWhenPrepared = getCurrentPosition();
            release(true);
        }
    };

    /**
     * release the media player in any state
     *
     * @param cleartargetstate
     */
    private void release(boolean cleartargetstate) {
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
            mMediaPlayer.release();
            mMediaPlayer = null;
            mCurrentState = MediaPlayerStatus.STATE_IDLE;
            StateChange(mCurrentState);
            if (cleartargetstate) {
                mTargetState = MediaPlayerStatus.STATE_IDLE;
            }
        }

    }

    private void StateChange(int mCurrentState) {
        if (mStateChangeListener != null) {
            mStateChangeListener.onChange(mCurrentState);
        }

    }

    private VideoViewStateChangeListener mStateChangeListener;

    public void setStateChangeListener(VideoViewStateChangeListener mStateChangeListener) {
        this.mStateChangeListener = mStateChangeListener;
    }

    public interface VideoViewStateChangeListener {
        public void onChange(int mCurrentState);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isInPlaybackState() && mMediaController != null) {
            toggleMediaControlsVisibility();
        }
        return false;
    }

    @Override
    public boolean onTrackballEvent(MotionEvent event) {
        if (isInPlaybackState() && mMediaController != null) {
            toggleMediaControlsVisibility();
        }
        return false;
    }

    @Override
    public void start() {

    }

    @Override
    public void pause() {

    }

    @Override
    public int getDuration() {
        return 0;
    }

    @Override
    public int getCurrentPosition() {
        return 0;
    }

    @Override
    public void seekTo(int i) {

    }


    @Override
    public boolean isPlaying() {
        return false;
    }

    @Override
    public int getBufferPercentage() {
        return 0;
    }

    @Override
    public boolean canPause() {
        return false;
    }

    @Override
    public boolean canSeekBackward() {
        return false;
    }

    @Override
    public boolean canSeekForward() {
        return false;
    }

    @Override
    public int getAudioSessionId() {
        return 0;
    }

    private int mCurrentBufferPercentage;

    private void openVideo() {
        if (mUri == null)
            return;
        if (mSurfaceHolder == null) {
            getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            setVisibility(VISIBLE);
            return;
        }
        //TODO 猜测如果当前用户有其他类似音乐播放器在播放时要暂停
        Intent i = new Intent("com.android.music.musicservicecommand");
        i.putExtra("command", "pause");
        mContext.sendBroadcast(i);
        release(false);


        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnPreparedListener(mPreparedListener);
        mMediaPlayer.setOnInfoListener(mInfoListener);
        mMediaPlayer.setOnVideoSizeChangedListener(mVideoSizeChangedListener);
        mMediaPlayer.setOnCompletionListener(mCompletionListener);
        mMediaPlayer.setOnErrorListener(mErrorListener);
        mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
        mDuration = -1;
        mCurrentBufferPercentage = 0;
        try {
            mMediaPlayer.setDataSource(mContext, mUri);
        } catch (IOException e) {
            Log.e(TAG, "Unable to open content: " + mUri, e);
            mCurrentState = MediaPlayerStatus.STATE_ERROR;
            StateChange(mCurrentState);
            mTargetState = MediaPlayerStatus.STATE_ERROR;
            mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
            return;

        }
        mMediaPlayer.setDisplay(mSurfaceHolder);
        mMediaPlayer.setAudioStreamType(AudioManager.ADJUST_MUTE);
        mMediaPlayer.setScreenOnWhilePlaying(true);
        mMediaPlayer.prepareAsync();
        mCurrentState = MediaPlayerStatus.STATE_PREPARING;
        StateChange(mCurrentState);
        attachMediaController();


    }


    private MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {

        }
    };
    private MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
        @Override
        public boolean onInfo(MediaPlayer mediaPlayer, int with, int height) {
            mCurrentState = MediaPlayerStatus.STATE_INFO;
            StateChange(mCurrentState);
            return false;
        }
    };
    private MediaPlayer.OnVideoSizeChangedListener mVideoSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(MediaPlayer mediaPlayer, int with, int height) {
            mVideoHeight = mediaPlayer.getVideoHeight();
            mVideoWidth = mediaPlayer.getVideoWidth();
            if (mVideoHeight != 0 && mVideoWidth != 0) {
                getHolder().setFixedSize(mVideoWidth, mVideoHeight);
            }
        }
    };
    private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            mCurrentState = MediaPlayerStatus.STATE_PLAYBACK_COMPLETED;
            StateChange(mCurrentState);
            mTargetState = MediaPlayerStatus.STATE_PLAYBACK_COMPLETED;
            mCurrentState = MediaPlayerStatus.STATE_STOPBACK;
            if (mMediaController != null) {
                mMediaController.hide();
            }
            if (mCompletionListener != null) {
                mCompletionListener.onCompletion(mMediaPlayer);
            }
        }
    };

    private MediaPlayer.OnErrorListener mErrorListener = new MediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(MediaPlayer mediaPlayer, int framework_err, int impl_err) {
            Log.d(TAG, "Error: " + framework_err + "," + impl_err);
            mCurrentState = MediaPlayerStatus.STATE_ERROR;
            StateChange(mCurrentState);
            mTargetState = MediaPlayerStatus.STATE_ERROR;
            if (mMediaController != null) {
                mMediaController.hide();
            }
            if (mErrorListener != null) {
                if (mErrorListener.onError(mMediaPlayer, framework_err, impl_err)) {
                    return false;
                }
            }
            return true;
        }
    };
    private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {
        @Override
        public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {

        }
    };

    public boolean isInPlaybackState() {
        return (mMediaPlayer != null && mCurrentState != MediaPlayerStatus.STATE_ERROR && mCurrentState != MediaPlayerStatus.STATE_IDLE && mCurrentState != MediaPlayerStatus.STATE_PREPARING);
    }


    private void attachMediaController() {
        if (mMediaPlayer != null && mMediaController != null) {
            mMediaController.setMediaPlayer(this);
            View anchorView = this.getParent() instanceof View ? (View) this.getParent() : this;
            mMediaController.setAnchorView(anchorView);
            mMediaController.setEnabled(isInPlaybackState());
        }
    }

    private void toggleMediaControlsVisibility() {
        if (mMediaController.isShowing()) {
            mMediaController.hide();
        } else {
            mMediaController.show();
        }
    }
}
